/*
 * Created on 2005/8/29
 * Created by Andy Chuang
 * contact:cut7man@hotmail.com
 */
package tw.cuttle.view.parameter;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.fileupload.servlet.ServletRequestContext;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import tw.cuttle.CuttleContext;

//import tw.cuttle.util.parameter.upload.ProgressListenerWrap;


/**
 * @author Andy Chuang
 *
 */
public class ParameterDigester {
	private ParameterDigester(){}
    private static Log log=LogFactory.getLog(ParameterDigester.class);

    /**
     * 
     */
    public static Object parseRequest(String formClass){
    	try {
	    Map<String, Object> properties=parseRequest();
	    	Class form=Class.forName(formClass);
	    	Object formObj=form.newInstance();
	    	BeanUtils.populate(formObj, properties);
	    	return formObj;
	} catch (Exception e) {
	    throw new RuntimeException(e);
	}
    }
    public static Object parse(Class formClass){
    	try {
	    Map<String, Object> properties=parseRequest();
	    Object formObject=formClass.newInstance();
	    BeanUtils.populate(formObject, properties);
	    return formObject;
	} catch (Exception e) {
	    throw new RuntimeException(e);
	}
    }
    public static Object parse(Object formObj){
    	try {
	    Map<String, Object> properties=parseRequest();
	    BeanUtils.populate(formObj, properties);
	    return formObj;
	} catch (Exception e) {
	    throw new RuntimeException(e);
	}
    }
    public static DynaForm parse(Map<String, Object> map){
    	Map<String, Object> properties=parseRequest(map);
    	DynaForm form=new DynaForm();
    	form.setParameters(properties);
    	return form;
    }
    public static DynaForm parse(){
	log.info("-----in parse");
    	Map<String, Object> properties=parseRequest();
    	log.info(properties);
    	DynaForm form=new DynaForm();
    	form.setParameters(properties);
    	return form;
    }
    public static Map<String, Object> parseRequest(){
    	return parseRequest(new HashMap<String, Object>());
    }
	public static Map<String, Object> parseRequest(Map<String, Object> properties){
	    Map<String, Object> parameterValues=CuttleContext.getActionContext().getActionHelper().getRequest().getParameterMap();
	    if(properties==null)properties=new HashMap<String, Object>();
//		 Create a factory for disk-based file items
		FileItemFactory factory = new DiskFileItemFactory();
//		 Create a new file upload handler
		ServletFileUpload upload = new ServletFileUpload(factory);
		//upload.setHeaderEncoding(encoding);
	
		ServletRequestContext context=new ServletRequestContext(CuttleContext.getActionContext().getActionHelper().getRequest());

		boolean isMultipart=ServletFileUpload.isMultipartContent(context);
		if(isMultipart){
			try{
//				 Parse the request
				List<FileItem> /* FileItem */ fileItems = upload.parseRequest(context);
				Iterator<FileItem> iter = fileItems.iterator();
				while (iter.hasNext()) {
					FileItem fi = iter.next();
					String fieldName=fi.getFieldName();
					if(fi.isFormField()){
						String property=fi.getString(context.getCharacterEncoding());
						if(properties.get(fieldName)!=null){
						    String strSplit[]=null;
						    if(properties.get(fieldName) instanceof String[]){
						        String strInProperties[]=(String[])properties.get(fieldName);
						        strSplit=new String[strInProperties.length+1];
						        for(int i=0;i<strInProperties.length;i++){
						            strSplit[i]=strInProperties[i];
						        }
						        strSplit[strInProperties.length]=property;
						    }else{
						        String strInProperties=(String)properties.get(fieldName);
						        strSplit=new String[2];
						        strSplit[0]=strInProperties;
						        strSplit[1]=property;
						    }
						    properties.put(fieldName,strSplit);
						}else{
							properties.put(fieldName, property);
						}
					}else{
					    FormFile property=new FormFileImpl(fi);
						if(properties.get(fieldName)!=null){
						    FormFile formSplit[]=null;
						    if(properties.get(fieldName) instanceof FormFile[]){

						        FormFile formFileInProperties[]=(FormFile[])properties.get(fieldName);
						        formSplit=new FormFile[formFileInProperties.length+1];
						        for(int i=0;i<formFileInProperties.length;i++){
						            formSplit[i]=formFileInProperties[i];
						        }
						        formSplit[formFileInProperties.length]=property;
						    }else{
						        FormFile FormFileInProperties=(FormFile)properties.get(fieldName);
						        formSplit=new FormFile[2];
						        formSplit[0]=FormFileInProperties;
						        formSplit[1]=property;
						    }
						    properties.put(fieldName,formSplit);
						}else{
							properties.put(fieldName, property);
						}
					}
				}
			} catch (Exception e) {
				log.debug(e);
				e.printStackTrace();
			}
		}else{
			Set keySet=parameterValues.keySet();
			Iterator iter=keySet.iterator();
            while(iter.hasNext()){
            	String fieldName=iter.next().toString();
            	Object property=parameterValues.get(fieldName);
            	
				if(properties.get(fieldName)!=null){
				    String strSplit[]=null;
				    if(properties.get(fieldName) instanceof String[]){
				        String strInProperties[]=(String[])properties.get(fieldName);
				        strSplit=new String[strInProperties.length+1];
				        for(int i=0;i<strInProperties.length;i++){
				            strSplit[i]=strInProperties[i];
				        }
				        strSplit[strInProperties.length]=property.toString();
				    }else{
				        String strInProperties=(String)properties.get(fieldName);
				        strSplit=new String[2];
				        strSplit[0]=strInProperties;
				        strSplit[1]=property.toString();
				    }
				    properties.put(fieldName,strSplit);
				}else{
					if(property instanceof String[]){
						if(((String[])property).length>1){
							properties.put(fieldName, property);
						}else{
							properties.put(fieldName, ((String[])property)[0]);
						}
					}else{
						properties.put(fieldName, property);
					}
				}
            }
		}
		return properties;
	}
}
